home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / irit / freefrm2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-12  |  54.9 KB  |  1,354 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d (not only polygonal) solid modeller.             *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Mar. 1990   *
  5. ******************************************************************************
  6. *   Module to provide the required interfact for the cagd library for the    *
  7. * free form surfaces and curves.                         *
  8. *****************************************************************************/
  9.  
  10. #include <stdio.h>
  11. #include <math.h>
  12. #include "program.h"
  13. #include "allocate.h"
  14. #include "attribut.h"
  15. #include "objects.h"
  16. #include "primitiv.h"
  17. #include "windows.h"
  18. #include "ip_cnvrt.h"
  19. #include "freeform.h"
  20.  
  21. #define MIN_FREE_FORM_RES 2
  22.  
  23. static IPObjectStruct *ComputeCurveIsoLines(IPObjectStruct *PObj,
  24.                         int Optimal);
  25. static IPObjectStruct *ComputeSurfaceIsoLines(IPObjectStruct *PObj,
  26.                           int Optimal);
  27. static IPObjectStruct *ComputeTrimSrfIsoLines(IPObjectStruct *PObj,
  28.                           int Optimal);
  29. static IPObjectStruct *ComputeTrivarIsoLines(IPObjectStruct *PObj,
  30.                          int Optimal);
  31.  
  32. /*****************************************************************************
  33. * DESCRIPTION:                                                               M
  34. * Routine to reverse a curve.                             M
  35. *                                                                            *
  36. * PARAMETERS:                                                                M
  37. *   CrvObj:     Curve to reverse its parametrization.                        M
  38. *                                                                            *
  39. * RETURN VALUE:                                                              M
  40. *   IPObjectStruct *:    Reversed curve.                                     M
  41. *                                                                            *
  42. * KEYWORDS:                                                                  M
  43. *   CurveReverse                                                             M
  44. *****************************************************************************/
  45. IPObjectStruct *CurveReverse(IPObjectStruct *CrvObj)
  46. {
  47.      CagdCrvStruct
  48.     *RevCrv = CagdCrvReverse(CrvObj -> U.Crvs);
  49.  
  50.     if (RevCrv == NULL)
  51.     return NULL;
  52.  
  53.     CrvObj = GenCRVObject(RevCrv);
  54.  
  55.     return CrvObj;
  56. }
  57.  
  58. /*****************************************************************************
  59. * DESCRIPTION:                                                               M
  60. * Routine to reverse a surface.                             M
  61. *                                                                            *
  62. * PARAMETERS:                                                                M
  63. *   SrfObj:     Surface to reverse.                                          M
  64. *                                                                            *
  65. * RETURN VALUE:                                                              M
  66. *   IPObjectStruct *:    Reversed surface. The normal of the reversed        M
  67. *                        surface is flipped with respected to the original   M
  68. *                        surface, SrfObj, by 180 degrees.             M
  69. *                                                                            *
  70. * KEYWORDS:                                                                  M
  71. *   SurfaceReverse                                                           M
  72. *****************************************************************************/
  73. IPObjectStruct *SurfaceReverse(IPObjectStruct *SrfObj)
  74. {
  75.     CagdSrfStruct
  76.     *RevSrf = CagdSrfReverse(SrfObj -> U.Srfs);
  77.  
  78.     if (RevSrf == NULL)
  79.     return NULL;
  80.  
  81.     SrfObj = GenSRFObject(RevSrf);
  82.  
  83.     return SrfObj;
  84. }
  85.  
  86. /*****************************************************************************
  87. * DESCRIPTION:                                                               *
  88. * Routine to convert curve(s) to a piecewise linear polyline approximation   *
  89. * and convert its control polygon into polyline as well.             *
  90. *                                                                            *
  91. * PARAMETERS:                                                                *
  92. *   PObj:       Curves to approximate using piecewise linear approximation.  *
  93. *   Optimal:    Do we want an optimal sampling but expensive approach?       *
  94. *                                                                            *
  95. * RETURN VALUE:                                                              *
  96. *   IPObjectStruct *:   A polyline approximation to PObj.                    *
  97. *****************************************************************************/
  98. static IPObjectStruct *ComputeCurveIsoLines(IPObjectStruct *PObj, int Optimal)
  99. {
  100.     int Resolution = GetResolution(FALSE);
  101.     IPObjectStruct *PObjPoly;
  102.     CagdCrvStruct *Crv;
  103.  
  104.     if (!IP_IS_CRV_OBJ(PObj))
  105.     IritFatalError("Curve was expected.");
  106.  
  107.     if (Resolution < MIN_FREE_FORM_RES)
  108.     Resolution = MIN_FREE_FORM_RES;
  109.  
  110.     PObjPoly = GenPOLYObject(NULL);
  111.     PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  112.     IP_SET_POLYLINE_OBJ(PObjPoly);
  113.     for (Crv = PObj -> U.Crvs; Crv != NULL; Crv = Crv -> Pnext) {
  114.     IPPolygonStruct *Poly;
  115.  
  116.     Poly = IritCurve2Polylines(Crv, Resolution, Optimal);
  117.  
  118.     Poly -> Pnext = PObjPoly -> U.Pl;
  119.     PObjPoly -> U.Pl = Poly;
  120.     }
  121.  
  122.     return PObjPoly;
  123. }
  124.  
  125. /*****************************************************************************
  126. * DESCRIPTION:                                                               *
  127. * Routine to convert a surface to a set of piecewise linear polyline         *
  128. * approximation and convert its control mesh into set of polyline as well.   *
  129. *                                                                            *
  130. * PARAMETERS:                                                                *
  131. *   PObj:        Surfaces to apporximate as a mesh of piecewise linear       *
  132. *         isocurves.                                                  *
  133. *   Optimal:     Do we want an optimal sampling but expensive approach?      *
  134. *                                                                            *
  135. * RETURN VALUE:                                                              *
  136. *   IPObjectStruct *:  A polyline object approximating PObj.                 *
  137. *****************************************************************************/
  138. static IPObjectStruct *ComputeSurfaceIsoLines(IPObjectStruct *PObj,
  139.                           int Optimal)
  140. {
  141.     int Resolution = GetResolution(FALSE);
  142.     IPObjectStruct *PObjPolys;
  143.     CagdSrfStruct *Srf;
  144.  
  145.     if (!IP_IS_SRF_OBJ(PObj))
  146.     IritFatalError("Surface was expected.");
  147.  
  148.     if (Resolution < MIN_FREE_FORM_RES)
  149.     Resolution = MIN_FREE_FORM_RES;
  150.  
  151.     PObjPolys = GenPOLYObject(NULL);
  152.     PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  153.     IP_SET_POLYLINE_OBJ(PObjPolys);
  154.     for (Srf = PObj -> U.Srfs; Srf != NULL; Srf = Srf -> Pnext) {
  155.     int NumOfIso[2];
  156.     IPPolygonStruct *Polys, *PolyTmp;
  157.  
  158.     NumOfIso[0] = NumOfIso[1] = -Resolution;
  159.     Polys = IritSurface2Polylines(Srf, NumOfIso, Resolution, Optimal);
  160.  
  161.     for (PolyTmp = Polys;
  162.          PolyTmp -> Pnext != NULL;
  163.          PolyTmp = PolyTmp -> Pnext);
  164.     PolyTmp -> Pnext = PObjPolys -> U.Pl;
  165.     PObjPolys -> U.Pl = Polys;
  166.     }
  167.  
  168.     return PObjPolys;
  169. }
  170.  
  171. /*****************************************************************************
  172. * DESCRIPTION:                                                               *
  173. * Routine to convert a trimmed surface to a set of piecewise linear polyline *
  174. * approximation and convert its control mesh into set of polyline as well.   *
  175. *                                                                            *
  176. * PARAMETERS:                                                                *
  177. *   PObj:        Trimmed surfaces to apporximate as a mesh of piecewise      *
  178. *          linear isocurves.                                          *
  179. *   Optimal:     Do we want an optimal sampling but expensive approach?      *
  180. *                                                                            *
  181. * RETURN VALUE:                                                              *
  182. *   IPObjectStruct *:  A polyline object approximating PObj.                 *
  183. *****************************************************************************/
  184. static IPObjectStruct *ComputeTrimSrfIsoLines(IPObjectStruct *PObj,
  185.                           int Optimal)
  186. {
  187.     int Resolution = GetResolution(FALSE);
  188.     IPObjectStruct *PObjPolys;
  189.     TrimSrfStruct *TrimSrf;
  190.  
  191.     if (!IP_IS_TRIMSRF_OBJ(PObj))
  192.     IritFatalError("Trimmed surface was expected.");
  193.  
  194.     if (Resolution < MIN_FREE_FORM_RES)
  195.     Resolution = MIN_FREE_FORM_RES;
  196.  
  197.     PObjPolys = GenPOLYObject(NULL);
  198.     PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  199.     IP_SET_POLYLINE_OBJ(PObjPolys);
  200.     for (TrimSrf = PObj -> U.TrimSrfs;
  201.      TrimSrf != NULL;
  202.      TrimSrf = TrimSrf -> Pnext) {
  203.     int NumOfIso[2];
  204.     IPPolygonStruct *Polys, *PolyTmp;
  205.  
  206.     NumOfIso[0] = NumOfIso[1] = -Resolution;
  207.     Polys = IritTrimSrf2Polylines(TrimSrf, NumOfIso, Resolution, Optimal,
  208.                       TRUE, TRUE);
  209.  
  210.     for (PolyTmp = Polys;
  211.          PolyTmp -> Pnext != NULL;
  212.          PolyTmp = PolyTmp -> Pnext);
  213.     PolyTmp -> Pnext = PObjPolys -> U.Pl;
  214.     PObjPolys -> U.Pl = Polys;
  215.     }
  216.  
  217.     return PObjPolys;
  218. }
  219.  
  220. /*****************************************************************************
  221. * DESCRIPTION:                                                               *
  222. * Routine to convert a trimmed surface to a set of piecewise linear polyline *
  223. * approximation and convert its control mesh into set of polyline as well.   *
  224. *                                                                            *
  225. * PARAMETERS:                                                                *
  226. *   PObj:        Trimmed surfaces to apporximate as a mesh of piecewise      *
  227. *          linear isocurves.                                          *
  228. *   Optimal:     Do we want an optimal sampling but expensive approach?      *
  229. *                                                                            *
  230. * RETURN VALUE:                                                              *
  231. *   IPObjectStruct *:  A polyline object approximating PObj.                 *
  232. *****************************************************************************/
  233. static IPObjectStruct *ComputeTrivarIsoLines(IPObjectStruct *PObj,
  234.                          int Optimal)
  235. {
  236.     int Resolution = GetResolution(FALSE);
  237.     IPObjectStruct *PObjPolys;
  238.     TrivTVStruct *Trivar;
  239.  
  240.     if (!IP_IS_TRIVAR_OBJ(PObj))
  241.     IritFatalError("Trivariate function was expected.");
  242.  
  243.     if (Resolution < MIN_FREE_FORM_RES)
  244.     Resolution = MIN_FREE_FORM_RES;
  245.  
  246.     PObjPolys = GenPOLYObject(NULL);
  247.     PObjPolys -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  248.     IP_SET_POLYLINE_OBJ(PObjPolys);
  249.     for (Trivar = PObj -> U.Trivars;
  250.      Trivar != NULL;
  251.      Trivar = Trivar -> Pnext) {
  252.     int NumOfIso[3],
  253.         Res = MAX(Resolution / 2, 2);
  254.     IPPolygonStruct *Polys, *PolyTmp;
  255.  
  256.     NumOfIso[0] = NumOfIso[1] = NumOfIso[2] = -Res;
  257.     Polys = IritTrivar2Polylines(Trivar, NumOfIso, Resolution, Optimal);
  258.  
  259.     for (PolyTmp = Polys;
  260.          PolyTmp -> Pnext != NULL;
  261.          PolyTmp = PolyTmp -> Pnext);
  262.     PolyTmp -> Pnext = PObjPolys -> U.Pl;
  263.     PObjPolys -> U.Pl = Polys;
  264.     }
  265.  
  266.     return PObjPolys;
  267. }
  268.  
  269. /*****************************************************************************
  270. * DESCRIPTION:                                                               M
  271. * Routine to convert a surface to a set of polygons approximating it.         M
  272. *   Result is saved as an attribute on the surfaces.                 M
  273. *   If however approximation alread exists, no computation is performed.     M
  274. *                                                                            *
  275. * PARAMETERS:                                                                M
  276. *   PObj:      Surfaces to approximate using polygons.                       M
  277. *                                                                            *
  278. * RETURN VALUE:                                                              M
  279. *   void                                                                     M
  280. *                                                                            *
  281. * KEYWORDS:                                                                  M
  282. *   ComputeSurfacePolygons                                                   M
  283. *****************************************************************************/
  284. void ComputeSurfacePolygons(IPObjectStruct *PObj)
  285. {
  286.     int    Resolution = GetResolution(FALSE),
  287.     FourPerFlat = GetFourPerFlat(),
  288.     PolyApproxOpt = GetPolyApproxOptimal(),
  289.     PolyApproxUV = GetPolyApproxUV();
  290.     RealType
  291.     RelResolution = AttrGetObjectRealAttrib(PObj, "resolution"),
  292.     Tolerance =  GetPolyApproxTol();
  293.     IPPolygonStruct *Polys;
  294.     IPObjectStruct *PObjPoly;
  295.  
  296.     if (AttrGetObjectObjAttrib(PObj, "_polygons") != NULL)
  297.     return;
  298.  
  299.     if (Resolution < MIN_FREE_FORM_RES)
  300.     Resolution = MIN_FREE_FORM_RES;
  301.     if (RelResolution < IP_ATTR_BAD_REAL)
  302.     Resolution = REAL_TO_INT(Resolution * RelResolution);
  303.  
  304. #ifndef __MSDOS__
  305.     /* Make the resolution more reasonable (very slow on MSDOS). */
  306.     Resolution *= 2;
  307. #endif /* __MSDOS__ */
  308.  
  309.     if (AttrGetObjectStrAttrib(PObj, "twoperflat") != NULL)
  310.     FourPerFlat = FALSE;
  311.     if (AttrGetObjectStrAttrib(PObj, "fourperflat") != NULL)
  312.     FourPerFlat = TRUE;
  313.  
  314.     Polys = IritSurface2Polygons(PObj -> U.Srfs, FourPerFlat,
  315.                  PolyApproxOpt ? Tolerance : Resolution,
  316.                  PolyApproxUV, PolyApproxOpt);
  317.     PObjPoly = GenPolyObject("", Polys, NULL);
  318.     PObjPoly -> Attrs = AttrCopyAttributes(PObj -> Attrs);
  319.     AttrSetObjectObjAttrib(PObj, "_polygons", PObjPoly, FALSE);
  320. }
  321.  
  322. /*****************************************************************************
  323. * DESCRIPTION:                                                               M
  324. * Routine to convert a surface/list of surfaces into set of polygons.         M
  325. *                                                                            *
  326. * PARAMETERS:                                                                M
  327. *   Obj:       A geometry to convert and approximate using polygons.         M
  328. *   Normals:   Do we want normals as well (at vertices)?                     M
  329. *                                                                            *
  330. * RETURN VALUE:                                                              M
  331. *   IPObjectStruct *:   A polygonal object approximating Obj.                M
  332. *                                                                            *
  333. * KEYWORDS:                                                                  M
  334. *   Geometry2Polygons                                                        M
  335. *****************************************************************************/
  336. IPObjectStruct *Geometry2Polygons(IPObjectStruct *Obj, RealType *Normals)
  337. {
  338.     IPObjectStruct *PObj;
  339.  
  340.     if (IP_IS_SRF_OBJ(Obj)) {
  341.     if (AttrGetObjectObjAttrib(Obj, "_polygons") != NULL)
  342.         AttrFreeOneAttribute(&Obj -> Attrs, "_polygons");
  343.     ComputeSurfacePolygons(Obj);
  344.     PObj = CopyObject(NULL, AttrGetObjectObjAttrib(Obj, "_polygons"),
  345.                                     FALSE);
  346.     AttrSetObjectColor(PObj, GlblPrimColor);   /* Set its default color. */
  347.  
  348.     if (!REAL_PTR_TO_INT(Normals)) {
  349.         IPPolygonStruct *Pl;
  350.  
  351.         for (Pl = PObj -> U.Pl; Pl != NULL; Pl = Pl -> Pnext) {
  352.         IPVertexStruct
  353.             *V = Pl -> PVertex;
  354.  
  355.         do {
  356.             IP_RST_NORMAL_VRTX(V);
  357.  
  358.             V = V -> Pnext;
  359.         }
  360.         while (V != NULL && V != Pl -> PVertex);
  361.         }
  362.     }
  363.  
  364.     return PObj;
  365.     }
  366.     else if (IP_IS_OLST_OBJ(Obj))
  367.     {
  368.     int i = 0;
  369.     IPPolygonStruct *P;
  370.     IPObjectStruct
  371.         *PObjAll = NULL;
  372.  
  373.         while ((PObj = ListObjectGet(Obj, i++)) != NULL) {
  374.         PObj = Geometry2Polygons(PObj, Normals);
  375.  
  376.         if (PObjAll) {
  377.         if (PObj -> U.Pl) {
  378.             for (P = PObj -> U.Pl;
  379.              P -> Pnext != NULL;
  380.              P = P -> Pnext);
  381.             P -> Pnext = PObjAll -> U.Pl;
  382.             PObjAll -> U.Pl = PObj -> U.Pl;
  383.             PObj -> U.Pl = NULL;
  384.         }
  385.         IPFreeObject(PObj);
  386.         }
  387.         else {
  388.         PObjAll = PObj;
  389.         }
  390.     }
  391.  
  392.     return PObjAll;
  393.     }
  394.     else {
  395.     WndwInputWindowPutStr("Unconvertable to polygons object ignored");
  396.     return NULL;
  397.     }
  398. }
  399.  
  400. /*****************************************************************************
  401. * DESCRIPTION:                                                               M
  402. * Routine to convert a surface/curve/list of these into set of polylines.    M
  403. *                                                                            *
  404. * PARAMETERS:                                                                M
  405. *   Obj:       A geometry to convert and approximate using polygons.         M
  406. *   Optimal:   Do we want an optimal sampling but expensive approach?        M
  407. *                                                                            *
  408. * RETURN VALUE:                                                              M
  409. *   IPObjectStruct *:   A polyline object approximating Obj.                 M
  410. *                                                                            *
  411. * KEYWORDS:                                                                  M
  412. *   Geometry2Polylines                                                       M
  413. *****************************************************************************/
  414. IPObjectStruct *Geometry2Polylines(IPObjectStruct *Obj, RealType *Optimal)
  415. {
  416.     IPObjectStruct *PObj;
  417.     IPPolygonStruct *P;
  418.  
  419.     if (IP_IS_CRV_OBJ(Obj)) {
  420.     return ComputeCurveIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  421.     }
  422.     else if (IP_IS_SRF_OBJ(Obj)) {
  423.     return ComputeSurfaceIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  424.     }
  425.     else if (IP_IS_TRIMSRF_OBJ(Obj)) {
  426.     return ComputeTrimSrfIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  427.     }
  428.     else if (IP_IS_TRIVAR_OBJ(Obj)) {
  429.     return ComputeTrivarIsoLines(Obj, REAL_PTR_TO_INT(Optimal));
  430.     }
  431.     else if (IP_IS_OLST_OBJ(Obj))
  432.     {
  433.     int i = 0;
  434.     IPObjectStruct
  435.         *PObjAll = NULL;
  436.  
  437.         while ((PObj = ListObjectGet(Obj, i++)) != NULL) {
  438.         PObj = Geometry2Polylines(PObj, Optimal);
  439.  
  440.         if (PObjAll) {
  441.         if (PObj -> U.Pl) {
  442.             for (P = PObj -> U.Pl;
  443.              P -> Pnext != NULL;
  444.              P = P -> Pnext);
  445.             P -> Pnext = PObjAll -> U.Pl;
  446.             PObjAll -> U.Pl = PObj -> U.Pl;
  447.             PObj -> U.Pl = NULL;
  448.         }
  449.         IPFreeObject(PObj);
  450.         }
  451.         else {
  452.         PObjAll = PObj;
  453.         }
  454.     }
  455.  
  456.     return PObjAll;
  457.     }
  458.     else {
  459.     return NULL;
  460.     }
  461. }
  462.  
  463. /*****************************************************************************
  464. * DESCRIPTION:                                                               M
  465. * Routine to return extremum value of control mesh/polygon.             M
  466. *                                                                            *
  467. * PARAMETERS:                                                                M
  468. *   Obj:      Object to bound itsextremum possible values.                   M
  469. *   Min:      TRUE for minimum, FALSE for maximum.                           M
  470. *                                                                            *
  471. * RETURN VALUE:                                                              M
  472. *   IPObjectStruct *:   A control points with extremum values. Rational are  M
  473. *                       Correctly porjected back to Euclidean space.         M
  474. *                                                                            *
  475. * KEYWORDS:                                                                  M
  476. *   ExtremumControlPointVals                                                 M
  477. *****************************************************************************/
  478. IPObjectStruct *ExtremumControlPointVals(IPObjectStruct *Obj, CagdRType *Min)
  479. {
  480.     CagdBType
  481.     FindMin = REAL_PTR_TO_INT(Min);
  482.     CagdRType *Extremum,
  483.     **Points = NULL;
  484.     int Len = 0;
  485.     CagdPointType
  486.     PType  = CAGD_PT_E1_TYPE;
  487.  
  488.     if (IP_IS_SRF_OBJ(Obj)) {
  489.     Points = Obj -> U.Srfs -> Points;
  490.     Len = Obj -> U.Srfs -> ULength * Obj -> U.Srfs -> VLength;
  491.     PType = Obj -> U.Srfs -> PType;
  492.     }
  493.     else if (IP_IS_CRV_OBJ(Obj)) {
  494.     Points = Obj -> U.Crvs -> Points;
  495.     Len = Obj -> U.Crvs -> Length;
  496.     PType = Obj -> U.Crvs -> PType;
  497.     }
  498.     else {
  499.     IritPrsrFatalError("Extremum allowed on curves/surfaces only");
  500.     return NULL;
  501.     }
  502.  
  503.     Extremum = SymbExtremumCntPtVals(Points, Len, FindMin);
  504.  
  505.     return GenCTLPTObject(PType, Extremum, NULL);
  506. }
  507.  
  508. /*****************************************************************************
  509. * DESCRIPTION:                                                               M
  510. * Creates an exact rational quadratic circle parallel to the XY plane.         M
  511. *                                                                            *
  512. * PARAMETERS:                                                                M
  513. *   Position:   Center of circle.                                            M
  514. *   Radius:     Radius of circle.                                            M
  515. *                                                                            *
  516. * RETURN VALUE:                                                              M
  517. *   IPObjectStruct *:   A rational quadratic Bspline curve object          M
  518. *            representing a circle.                     M
  519. *                                                                            *
  520. * KEYWORDS:                                                                  M
  521. *   GenCircleCurveObject                                                     M
  522. *****************************************************************************/
  523. IPObjectStruct *GenCircleCurveObject(VectorType Position, RealType *Radius)
  524. {
  525.     int i;
  526.     CagdPtStruct Pos;
  527.     CagdCrvStruct *CircCrv;
  528.     IPObjectStruct *CrvObj;
  529.  
  530.     for (i = 0; i < 3; i++)
  531.     Pos.Pt[i] = Position[i];
  532.     CircCrv = BspCrvCreateCircle(&Pos, *Radius);
  533.  
  534.     if (CircCrv == NULL)
  535.     return NULL;
  536.  
  537.     CrvObj = GenCRVObject(CircCrv);
  538.  
  539.     return CrvObj;
  540. }
  541.  
  542. /*****************************************************************************
  543. * DESCRIPTION:                                                               M
  544. * Creates an approximated cubic polynomial circle parallel to the XY plane.  M
  545. *                                                                            *
  546. * PARAMETERS:                                                                M
  547. *   Position:   Center of circle.                                            M
  548. *   Radius:     Radius of circle.                                            M
  549. *                                                                            *
  550. * RETURN VALUE:                                                              M
  551. *   IPObjectStruct *:   A cubic polynomial Bspline curve object          M
  552. *            representing a circle.                     M
  553. *                                                                            *
  554. * KEYWORDS:                                                                  M
  555. *   GenPCircleCurveObject                                                    M
  556. *****************************************************************************/
  557. IPObjectStruct *GenPCircleCurveObject(VectorType Position, RealType *Radius)
  558. {
  559.     int i;
  560.     CagdPtStruct Pos;
  561.     CagdCrvStruct *CircCrv;
  562.     IPObjectStruct *CrvObj;
  563.  
  564.     for (i = 0; i < 3; i++)
  565.     Pos.Pt[i] = Position[i];
  566.     CircCrv = BspCrvCreatePCircle(&Pos, *Radius);
  567.  
  568.     if (CircCrv == NULL)
  569.     return NULL;
  570.  
  571.     CrvObj = GenCRVObject(CircCrv);
  572.  
  573.     return CrvObj;
  574. }
  575.  
  576. /*****************************************************************************
  577. * DESCRIPTION:                                                               M
  578. * Creates an arbitrary arc specified by Two end points and Center. Arc must  M
  579. * be less than 180 degree.                             M
  580. *                                                                            *
  581. * PARAMETERS:                                                                M
  582. *   Start:    Location of arc.                                               M
  583. *   Center:   Location of arc.                                               M
  584. *   End:      Location of arc.                                               M
  585. *                                                                            *
  586. * RETURN VALUE:                                                              M
  587. *   IPObjectStruct *:  A curve representing the requested arc.               M
  588. *                                                                            *
  589. * KEYWORDS:                                                                  M
  590. *   GenArcCurveObject                                                        M
  591. *****************************************************************************/
  592. IPObjectStruct *GenArcCurveObject(VectorType Start,
  593.                   VectorType Center,
  594.                   VectorType End)
  595. {
  596.     int i;
  597.     CagdPtStruct StartPt, CenterPt, EndPt;
  598.     CagdCrvStruct *ArcCrv;
  599.     IPObjectStruct *CrvObj;
  600.  
  601.     for (i = 0; i < 3; i++) {
  602.     StartPt.Pt[i] = Start[i];
  603.     CenterPt.Pt[i] = Center[i];
  604.     EndPt.Pt[i] = End[i];
  605.     }
  606.     ArcCrv = BzrCrvCreateArc(&StartPt, &CenterPt, &EndPt);
  607.  
  608.     if (ArcCrv == NULL)
  609.     return NULL;
  610.  
  611.     CrvObj = GenCRVObject(ArcCrv);
  612.  
  613.     return CrvObj;
  614. }
  615.  
  616. /*****************************************************************************
  617. * DESCRIPTION:                                                               M
  618. * Constructs a ruled surface out of the two provided curves.             M
  619. *                                                                            *
  620. * PARAMETERS:                                                                M
  621. *   Crv1, Crv2:  Two curves to rule a surface between.                       M
  622. *                                                                            *
  623. * RETURN VALUE:                                                              M
  624. *   IPObjectStruct *: A ruled surface object.                                M
  625. *                                                                            *
  626. * KEYWORDS:                                                                  M
  627. *   GenRuledSrfObject                                                        M
  628. *****************************************************************************/
  629. IPObjectStruct *GenRuledSrfObject(IPObjectStruct *Crv1, IPObjectStruct *Crv2)
  630. {
  631.     IPObjectStruct *SrfObj;
  632.     CagdSrfStruct
  633.     *RuledSrf = CagdRuledSrf(Crv1 -> U.Crvs, Crv2 -> U.Crvs, 2, 2);
  634.  
  635.     if (RuledSrf == NULL)
  636.     return NULL;
  637.  
  638.     SrfObj = GenSRFObject(RuledSrf);
  639.  
  640.     return SrfObj;
  641. }
  642.  
  643. /*****************************************************************************
  644. * DESCRIPTION:                                                               M
  645. * Construct a boolean sum surface out of a single boundary curve.         M
  646. *                                                                            *
  647. * PARAMETERS:                                                                M
  648. *   BndryCrv:  A curve to fill its interior with a surface. Better be close. M
  649. *                                                                            *
  650. * RETURN VALUE:                                                              M
  651. *   IPObjectStruct *: A filling surface object.                              M
  652. *                                                                            *
  653. * KEYWORDS:                                                                  M
  654. *   GenBoolOneSrfObject                                                      M
  655. *****************************************************************************/
  656. IPObjectStruct *GenBoolOneSrfObject(IPObjectStruct *BndryCrv)
  657. {
  658.     IPObjectStruct *SrfObj;
  659.     CagdSrfStruct
  660.     *BoolSumSrf = CagdOneBoolSumSrf(BndryCrv -> U.Crvs);
  661.  
  662.     if (BoolSumSrf == NULL)
  663.     return NULL;
  664.  
  665.     SrfObj = GenSRFObject(BoolSumSrf);
  666.  
  667.     return SrfObj;
  668. }
  669.  
  670. /*****************************************************************************
  671. * DESCRIPTION:                                                               M
  672. * Construct a boolean sum surface out of the four provided curves.         M
  673. *                                                                            *
  674. * PARAMETERS:                                                                M
  675. *   Crv1, Crv2, Crv3, Crv4:  Four curves to construct a Boolean sum between. M
  676. *                                                                            *
  677. * RETURN VALUE:                                                              M
  678. *   IPObjectStruct *:  The Boolean sum surface.                              M
  679. *                                                                            *
  680. * KEYWORDS:                                                                  M
  681. *   GenBoolSumSrfObject                                                      M
  682. *****************************************************************************/
  683. IPObjectStruct *GenBoolSumSrfObject(IPObjectStruct *Crv1,
  684.                     IPObjectStruct *Crv2,
  685.                     IPObjectStruct *Crv3,
  686.                     IPObjectStruct *Crv4)
  687. {
  688.     IPObjectStruct *SrfObj;
  689.     CagdSrfStruct
  690.     *BoolSumSrf = CagdBoolSumSrf(Crv1 -> U.Crvs,
  691.                      Crv2 -> U.Crvs,
  692.                      Crv3 -> U.Crvs,
  693.                      Crv4 -> U.Crvs);
  694.  
  695.     if (BoolSumSrf == NULL)
  696.     return NULL;
  697.  
  698.     SrfObj = GenSRFObject(BoolSumSrf);
  699.  
  700.     return SrfObj;
  701. }
  702.  
  703. /*****************************************************************************
  704. * DESCRIPTION:                                                               M
  705. * Construct a surface out of the provided curve list.                 M
  706. *                                                                            *
  707. * PARAMETERS:                                                                M
  708. *   CrvList:     A list of curves to approximate a surface through.          M
  709. *   OtherOrder:  Other order of surface.                                     M
  710. *                                                                            *
  711. * RETURN VALUE:                                                              M
  712. *   IPObjectStruct *:   A surface approximately traversing through the given M
  713. *                       curves.                                              M
  714. *                                                                            *
  715. * KEYWORDS:                                                                  M
  716. *   GenSrfFromCrvsObject                                                     M
  717. *****************************************************************************/
  718. IPObjectStruct *GenSrfFromCrvsObject(IPObjectStruct *CrvList,
  719.                      RealType *OtherOrder)
  720. {
  721.     int i,
  722.     NumCrvs = 0;
  723.     IPObjectStruct *SrfObj, *CrvObj, *PrevCrvObj, *HeadCrvObj;
  724.     CagdSrfStruct *Srf;
  725.     CagdCrvStruct *Crv,
  726.     *Crvs = NULL;
  727.  
  728.  
  729.     if (!IP_IS_OLST_OBJ(CrvList))
  730.     IritFatalError("SURFACE: Not object list object!");
  731.  
  732.     while ((CrvObj = ListObjectGet(CrvList, NumCrvs)) != NULL) {
  733.     if (!IP_IS_CRV_OBJ(CrvObj)) {
  734.         IritPrsrFatalError("SURFACE: List contains non curve object(s).");
  735.         return NULL;
  736.     }
  737.     if (CrvObj -> U.Crvs -> Pnext != NULL) {
  738.         IritPrsrFatalError("SURFACE: nested curve lists are disallowed.");
  739.         return NULL;
  740.     }
  741.     NumCrvs++;
  742.     }
  743.  
  744.     /* Chain all curves into a single list and invoke the srf constructor: */
  745.     HeadCrvObj = PrevCrvObj = ListObjectGet(CrvList, 0);
  746.     for (i = 0; i < NumCrvs; i++) {
  747.     CrvObj = ListObjectGet(CrvList, i);
  748.     Crv = CagdCrvCopy(CrvObj -> U.Crvs);
  749.     LIST_PUSH(Crv, Crvs);
  750.     }
  751.  
  752.     Crvs = CagdListReverse(Crvs);
  753.     Srf = CagdSrfFromCrvs(Crvs, REAL_PTR_TO_INT(OtherOrder));
  754.     CagdCrvFreeList(Crvs);
  755.  
  756.     if (Srf == NULL)
  757.     return NULL;
  758.  
  759.     SrfObj = GenSRFObject(Srf);
  760.  
  761.     return SrfObj;
  762. }
  763.  
  764. /*****************************************************************************
  765. * DESCRIPTION:                                                               M
  766. * Constructs a Sweep surface out of the CrossSection curve, Axis curve and   M
  767. * optional Scaling curve and Scaler which scales the CrossSection.         M
  768. *                                                                            *
  769. * PARAMETERS:                                                                M
  770. *   CrossSection:  Cross section of sweep.                                   M
  771. *   Axis:          Axis curve of sweep.                                      M
  772. *   Frame:         Orientation specification. Either an orientation curve    M
  773. *           Or a vector specification.                     M
  774. *                                                                            *
  775. * RETURN VALUE:                                                              M
  776. *   IPObjectStruct *:  A sweep surface.                                      M
  777. *                                                                            *
  778. * KEYWORDS:                                                                  M
  779. *   GenSweepSrfObject                                                        M
  780. *****************************************************************************/
  781. IPObjectStruct *GenSweepSrfObject(IPObjectStruct *CrossSection,
  782.                   IPObjectStruct *Axis,
  783.                   IPObjectStruct *Frame)
  784. {
  785.     IPObjectStruct *SrfObj;
  786.     int FrameIsCrv = IP_IS_CRV_OBJ(Frame),
  787.     HasFrame = FrameIsCrv || IP_IS_VEC_OBJ(Frame);
  788.     CagdSrfStruct *SweepSrf;
  789.  
  790.     SweepSrf = CagdSweepSrf(CrossSection -> U.Crvs, Axis -> U.Crvs, NULL, 1.0,
  791.                 HasFrame ? (FrameIsCrv
  792.                             ? (VoidPtr) Frame -> U.Crvs
  793.                             : (VoidPtr) Frame -> U.Vec)
  794.                      : NULL,
  795.                 FrameIsCrv);
  796.  
  797.     if (SweepSrf == NULL)
  798.     return NULL;
  799.  
  800.     SrfObj = GenSRFObject(SweepSrf);
  801.  
  802.     return SrfObj;
  803. }
  804.  
  805. /*****************************************************************************
  806. * DESCRIPTION:                                                               M
  807. * Constructs a Sweep surface out of the CrossSection curve, Axis curve and   M
  808. * optional Scaling curve and Scaler which scales the CrossSection.         M
  809. *                                                                            *
  810. * PARAMETERS:                                                                M
  811. *   CrossSection:  Cross section of sweep.                                   M
  812. *   Axis:          Axis curve of sweep.                                      M
  813. *   Scale:         Either a numeric constant scale or a scaling scalar curve.M
  814. *   Frame:         Orientation specification. Either an orientation curve    M
  815. *           Or a vector specification.                     M
  816. *   RRefine:       Refinement control.                                     M
  817. *                                                                            *
  818. * RETURN VALUE:                                                              M
  819. *   IPObjectStruct *:  A sweep surface.                                      M
  820. *                                                                            *
  821. * KEYWORDS:                                                                  M
  822. *   GenSweepScaleSrfObject                                                   M
  823. *****************************************************************************/
  824. IPObjectStruct *GenSweepScaleSrfObject(IPObjectStruct *CrossSection,
  825.                        IPObjectStruct *Axis,
  826.                        IPObjectStruct *Scale,
  827.                        IPObjectStruct *Frame,
  828.                        RealType *RRefine)
  829. {
  830.     IPObjectStruct *SrfObj;
  831.     int FrameIsCrv = IP_IS_CRV_OBJ(Frame),
  832.     HasFrame = FrameIsCrv || IP_IS_VEC_OBJ(Frame),
  833.     Refine = REAL_PTR_TO_INT(RRefine);
  834.     CagdCrvStruct
  835.     *AxisCrv = Axis -> U.Crvs;
  836.     CagdSrfStruct *SweepSrf;
  837.  
  838.     if (IP_IS_CRV_OBJ(Scale)) {
  839.     CagdCrvStruct
  840.         *TCrv = CagdSweepAxisRefine(AxisCrv, Scale -> U.Crvs, Refine);
  841.  
  842.     AxisCrv = TCrv;
  843.     }
  844.  
  845.     SweepSrf = CagdSweepSrf(CrossSection -> U.Crvs, AxisCrv,
  846.                 IP_IS_CRV_OBJ(Scale) ? Scale -> U.Crvs : NULL,
  847.                 IP_IS_NUM_OBJ(Scale) ? Scale -> U.R : 1.0,
  848.                 HasFrame ? (FrameIsCrv
  849.                             ? (VoidPtr) Frame -> U.Crvs
  850.                             : (VoidPtr) Frame -> U.Vec)
  851.                      : NULL,
  852.                 FrameIsCrv);
  853.  
  854.     if (AxisCrv != Axis -> U.Crvs)
  855.     CagdCrvFree(AxisCrv);
  856.  
  857.     if (SweepSrf == NULL)
  858.     return NULL;
  859.  
  860.     SrfObj = GenSRFObject(SweepSrf);
  861.  
  862.     return SrfObj;
  863. }
  864.  
  865. /*****************************************************************************
  866. * DESCRIPTION:                                                               M
  867. * Computes an approximation to the offset of a (planar) curve or a surface.  M
  868. *                                                                            *
  869. * PARAMETERS:                                                                M
  870. *   Obj:        Curve to approximate its offset by Offset amount.            M
  871. *   Offset:     Amount of offset.                                            M
  872. *   Tolerance:  Accuracy of offset.                                          M
  873. *   BezInterp:  Do we want Bezier interpolation or approximation?            M
  874. *                                                                            *
  875. * RETURN VALUE:                                                              M
  876. *   IPObjectStruct *:    An offset approximating to Obj.                     M
  877. *                                                                            *
  878. * KEYWORDS:                                                                  M
  879. *   GenOffsetObject                                                          M
  880. *****************************************************************************/
  881. IPObjectStruct *GenOffsetObject(IPObjectStruct *Obj,
  882.                 RealType *Offset,
  883.                 RealType *Tolerance,
  884.                 RealType *BezInterp)
  885. {
  886.     if (IP_IS_SRF_OBJ(Obj)) {
  887.         IPObjectStruct *SrfObj;
  888.         CagdSrfStruct
  889.         *OffsetSrf = SymbSrfSubdivOffset(Obj -> U.Srfs, *Offset,
  890.                          *Tolerance);
  891.  
  892.         if (OffsetSrf == NULL)
  893.         return NULL;
  894.  
  895.         SrfObj = GenSRFObject(OffsetSrf);
  896.  
  897.         return SrfObj;
  898.     }
  899.     else if (IP_IS_CRV_OBJ(Obj)) {
  900.         IPObjectStruct *CrvObj;
  901.         CagdCrvStruct
  902.         *OffsetCrv = SymbCrvSubdivOffset(Obj -> U.Crvs, *Offset,
  903.                          *Tolerance,
  904.                          REAL_PTR_TO_INT(BezInterp));
  905.  
  906.         if (OffsetCrv == NULL)
  907.         return NULL;
  908.  
  909.         CrvObj = GenCRVObject(OffsetCrv);
  910.  
  911.         return CrvObj;
  912.     }
  913.     else {
  914.     IritPrsrFatalError("Offset allowed on curves/surfaces only");
  915.     return NULL;
  916.     }
  917. }
  918.  
  919. /*****************************************************************************
  920. * DESCRIPTION:                                                               M
  921. * Computes an approximation to the offset of a (planar) curve or a surface.  M
  922. *   This offset is computed and approximated to with a given tolerance       M
  923. * Epsilon that is related to the square of the distance between the original M
  924. * curve and its offset approximation.                         M
  925. *   If Trim then regions in the curve with curvature that is larger than     M
  926. * offset distance required will be trimmed out.                     M
  927. *                                                                            *
  928. * PARAMETERS:                                                                M
  929. *   Obj:        Curve to approximate its offset by Offset amount.            M
  930. *   Offset:     Amount of offset.                                            M
  931. *   Epsilon:    Accuracy of offset.                                          M
  932. *   Trim:       Shouldwe deal and trim self intersecting loops?              M
  933. *   BezInterp:  Do we want Bezier interpolation or approximation?            M
  934. *                                                                            *
  935. * RETURN VALUE:                                                              M
  936. *   IPObjectStruct *:    An offset approximating to Obj.                     M
  937. *                                                                            *
  938. * KEYWORDS:                                                                  M
  939. *   GenAOffsetObject                                                         M
  940. *****************************************************************************/
  941. IPObjectStruct *GenAOffsetObject(IPObjectStruct *Obj,
  942.                  RealType *Offset,
  943.                  RealType *Epsilon,
  944.                  RealType *Trim,
  945.                  RealType *BezInterp)
  946. {
  947.     if (IP_IS_SRF_OBJ(Obj)) {
  948.     IritPrsrFatalError("Adaptive offset is not supported for surfaces");
  949.     return NULL;
  950.     }
  951.     else if (IP_IS_CRV_OBJ(Obj)) {
  952.         IPObjectStruct *CrvObj;
  953.         CagdCrvStruct
  954.         *OffsetCrv = APX_EQ(*Trim, 0.0) ?
  955.             SymbCrvAdapOffset(Obj -> U.Crvs, *Offset, *Epsilon,
  956.                   NULL, REAL_PTR_TO_INT(BezInterp)) :
  957.         SymbCrvAdapOffsetTrim(Obj -> U.Crvs, *Offset,
  958.                       *Epsilon, NULL,
  959.                       REAL_PTR_TO_INT(BezInterp));
  960.  
  961.         if (OffsetCrv == NULL)
  962.         return NULL;
  963.     else
  964.         CrvObj = GenCRVObject(OffsetCrv);
  965.  
  966.         return CrvObj;
  967.     }
  968.     else {
  969.     IritPrsrFatalError("Offset allowed on curves/surfaces only");
  970.     return NULL;
  971.     }
  972. }
  973.  
  974. /*****************************************************************************
  975. * DESCRIPTION:                                                               M
  976. * Computes an approximation to the offset of a (planar) curve or a surface.  M
  977. *   This offset is computed and approximated using a least sqaure fit.         M
  978. *                                                                            *
  979. * PARAMETERS:                                                                M
  980. *   Obj:          Curve to approximate its offset by Offset amount.          M
  981. *   Offset:       Amount of offset.                                          M
  982. *   NumOfSamples: To sample the offset curve.                                M
  983. *   NumOfDOF:     Number of control points in resulting approximation.       M
  984. *   Order:        Of resulting approximation.                                M
  985. *                                                                            *
  986. * RETURN VALUE:                                                              M
  987. *   IPObjectStruct *:    An offset approximating to Obj.                     M
  988. *                                                                            *
  989. * KEYWORDS:                                                                  M
  990. *   GenLeastSqrOffsetObject                                                  M
  991. *****************************************************************************/
  992. IPObjectStruct *GenLeastSqrOffsetObject(IPObjectStruct *Obj,
  993.                     RealType *Offset,
  994.                     RealType *NumOfSamples,
  995.                     RealType *NumOfDOF,
  996.                     RealType *Order)
  997. {
  998.     CagdRType Tolerance;
  999.  
  1000.     if (IP_IS_CRV_OBJ(Obj)) {
  1001.         CagdCrvStruct
  1002.         *OffsetCrv = SymbCrvLeastSquarOffset(Obj -> U.Crvs,
  1003.                          *Offset,
  1004.                          REAL_PTR_TO_INT(NumOfSamples),
  1005.                          REAL_PTR_TO_INT(NumOfDOF),
  1006.                          REAL_PTR_TO_INT(Order),
  1007.                          &Tolerance);
  1008.  
  1009.         if (OffsetCrv == NULL)
  1010.         return NULL;
  1011.     else
  1012.         return GenCRVObject(OffsetCrv);
  1013.     }
  1014.     else {
  1015.     IritPrsrFatalError("LOffset allowed on curves only");
  1016.     return NULL;
  1017.     }
  1018. }
  1019.  
  1020. /*****************************************************************************
  1021. * DESCRIPTION:                                                               M
  1022. * Affine reparametrization, effectively changing the domain of the curve.    M
  1023. *                                                                            *
  1024. * PARAMETERS:                                                                M
  1025. *   Obj:         A curve to change its parametric domain.                    M
  1026. *   TMin, TMax:  New domain for Obj.                         M
  1027. *                                                                            *
  1028. * RETURN VALUE:                                                              M
  1029. *   IPObjectStruct *:  A curve identical to Crv but with parametric domain   M
  1030. *                      from TMin to TMax.                                    M
  1031. *                                                                            *
  1032. * KEYWORDS:                                                                  M
  1033. *   CrvReparametrization                                                     M
  1034. *****************************************************************************/
  1035. IPObjectStruct *CrvReparametrization(IPObjectStruct *Obj,
  1036.                      RealType *TMin,
  1037.                      RealType *TMax)
  1038. {
  1039.     IPObjectStruct *CrvObj;
  1040.     CagdCrvStruct
  1041.     *Crv = CAGD_IS_BEZIER_CRV(Obj -> U.Crvs) ?
  1042.               CnvrtBezier2BsplineCrv(Obj -> U.Crvs) :
  1043.               CagdCrvCopy(Obj -> U.Crvs);
  1044.     int Len = Crv -> Length + Crv -> Order;
  1045.     CagdRType
  1046.     *KV = Crv -> KnotVector;
  1047.  
  1048.     /* Translate to 0.0, scale, and translate to new location. */
  1049.     BspKnotAffineTrans(KV, Len, -KV[0], 1.0);
  1050.     BspKnotAffineTrans(KV, Len, 0.0, (*TMax - *TMin) / (KV[Len - 1] - KV[0]));
  1051.     BspKnotAffineTrans(KV, Len, *TMin, 1.0);
  1052.     
  1053.     CrvObj = GenCRVObject(Crv);
  1054.  
  1055.     return CrvObj;
  1056. }
  1057.  
  1058. /*****************************************************************************
  1059. * DESCRIPTION:                                                               M
  1060. * Affine reparametrization, effectively changing the domain of the curve.    M
  1061. *                                                                            *
  1062. * PARAMETERS:                                                                M
  1063. *   Obj:         A surface to change its parametric domain.                  M
  1064. *   RDir:        Direction of reparametrization. Either U or V.             M
  1065. *   TMin, TMax:  New domain for Obj.                         M
  1066. *                                                                            *
  1067. * RETURN VALUE:                                                              M
  1068. *   IPObjectStruct *:  A surface identical to Srf but with parametric        M
  1069. *                      domain from TMin to TMax in direction RDir.           M
  1070. *                                                                            *
  1071. * KEYWORDS:                                                                  M
  1072. *   SrfReparametrization                                                     M
  1073. *****************************************************************************/
  1074. IPObjectStruct *SrfReparametrization(IPObjectStruct *Obj,
  1075.                      RealType *RDir,
  1076.                      RealType *TMin,
  1077.                      RealType *TMax)
  1078. {
  1079.     IPObjectStruct *SrfObj;
  1080.     CagdSrfDirType
  1081.     Dir = REAL_PTR_TO_INT(RDir);
  1082.     CagdSrfStruct
  1083.     *Srf = CAGD_IS_BEZIER_SRF(Obj -> U.Srfs) ?
  1084.               CnvrtBezier2BsplineSrf(Obj -> U.Srfs) :
  1085.               CagdSrfCopy(Obj -> U.Srfs);
  1086.     int Len = Dir == CAGD_CONST_U_DIR ? Srf -> ULength + Srf -> UOrder
  1087.                       : Srf -> VLength + Srf -> VOrder;
  1088.     CagdRType
  1089.         *KV = Dir == CAGD_CONST_U_DIR ? Srf -> UKnotVector : Srf -> VKnotVector;
  1090.  
  1091.     /* Translate to 0.0, scale, and translate to new location. */
  1092.     BspKnotAffineTrans(KV, Len, -KV[0], 1.0);
  1093.     BspKnotAffineTrans(KV, Len, 0.0, (*TMax - *TMin) / (KV[Len - 1] - KV[0]));
  1094.     BspKnotAffineTrans(KV, Len, *TMin, 1.0);
  1095.  
  1096.     SrfObj = GenSRFObject(Srf);
  1097.  
  1098.     return SrfObj;
  1099. }
  1100.  
  1101. /*****************************************************************************
  1102. * DESCRIPTION:                                                               M
  1103. * Computes curvature properties of the given curve.                 M
  1104. *                                                                            *
  1105. * PARAMETERS:                                                                M
  1106. *   PObj:      Curve to evaluate its curvature properties.                   M
  1107. *   Eps:       Accuracy of computation.                                      M
  1108. *                                                                            *
  1109. * RETURN VALUE:                                                              M
  1110. *   IPObjectStruct *:  Either extremum curvature locations if Eps > 0, or    M
  1111. *                      curvature field square curve if Eps < 0.              M
  1112. *                                                                            *
  1113. * KEYWORDS:                                                                  M
  1114. *   CrvCurvaturePts                                                          M
  1115. *****************************************************************************/
  1116. IPObjectStruct *CrvCurvaturePts(IPObjectStruct *PObj, RealType *Eps)
  1117.     IPObjectStruct *NewPObj;
  1118.  
  1119.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) < 2 ||
  1120.     CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) > 3) {
  1121.     IritPrsrFatalError(
  1122.         "CCRVTR: Only 2 or 3 dimensional curves are supported.");
  1123.     return NULL;
  1124.     }
  1125.  
  1126.     if (*Eps <= 0.0) {
  1127.     CagdRType TMin, TMax;
  1128.     CagdCrvStruct *CrvtrCrv2D,
  1129.         *CrvtrCrv = SymbCrv3DCurvatureSqr(PObj -> U.Crvs);
  1130.  
  1131.     CagdCrvDomain(PObj -> U.Crvs, &TMin, &TMax);
  1132.     CrvtrCrv2D = SymbPrmtSclrCrvTo2D(CrvtrCrv, TMin, TMax);
  1133.     CagdCrvFree(CrvtrCrv);
  1134.  
  1135.     NewPObj = GenCRVObject(CrvtrCrv2D);
  1136.     }
  1137.     else {
  1138.     int i;
  1139.     CagdPtStruct *IPtsTmp,
  1140.         *IPts = SymbCrv2DExtremCrvtrPts(PObj -> U.Crvs, *Eps);
  1141.  
  1142.     NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  1143.  
  1144.     for (IPtsTmp = IPts, i = 0;
  1145.          IPtsTmp != NULL;
  1146.          IPtsTmp = IPtsTmp -> Pnext, i++) {
  1147.         ListObjectInsert(NewPObj, i, GenNUMValObject(IPtsTmp -> Pt[0]));
  1148.     }
  1149.  
  1150.     CagdPtFreeList(IPts);
  1151.  
  1152.     ListObjectInsert(NewPObj, i, NULL);
  1153.     }
  1154.  
  1155.     return NewPObj;
  1156. }
  1157.  
  1158. /*****************************************************************************
  1159. * DESCRIPTION:                                                               M
  1160. * Computes curvature properties of the given surface.                 M
  1161. *                                                                            *
  1162. * PARAMETERS:                                                                M
  1163. *   PObj:     Surface to compute curvature properties for.                   M
  1164. *   RPtType:  Point type of output.                                          M
  1165. *   RDir:     Either curvature in U or V or total upper bound.               M
  1166. *                                                                            *
  1167. * RETURN VALUE:                                                              M
  1168. *   IPObjectStruct *:   A curvature bound field for surface PObj.            M
  1169. *                                                                            *
  1170. * KEYWORDS:                                                                  M
  1171. *   SrfCurvatureBounds                                                       M
  1172. *****************************************************************************/
  1173. IPObjectStruct *SrfCurvatureBounds(IPObjectStruct *PObj,
  1174.                    RealType *RPtType,
  1175.                    RealType *RDir)
  1176.     IPObjectStruct *NewPObj;
  1177.     CagdSrfStruct *TSrf, *CrvtrSrfBound;
  1178.     CagdPointType
  1179.     PtType = REAL_PTR_TO_INT(RPtType);
  1180.     CagdSrfDirType
  1181.     Dir = REAL_PTR_TO_INT(RDir);
  1182.  
  1183.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) < 2 ||
  1184.     CAGD_NUM_OF_PT_COORD(PObj -> U.Srfs -> PType) > 3) {
  1185.     IritPrsrFatalError(
  1186.         "SCRVTR: Only 2 or 3 dimensional curves are supported.");
  1187.     return NULL;
  1188.     }
  1189.  
  1190.     switch (Dir) {
  1191.     case CAGD_CONST_U_DIR:
  1192.     case CAGD_CONST_V_DIR:
  1193.         CrvtrSrfBound = SymbSrfIsoDirNormalCurvatureBound(PObj -> U.Srfs,
  1194.                                     Dir);
  1195.         break;
  1196.     default:
  1197.         CrvtrSrfBound = SymbSrfCurvatureUpperBound(PObj -> U.Srfs);
  1198.         break;
  1199.     }
  1200.  
  1201.     switch (PtType) {
  1202.     case CAGD_PT_P1_TYPE:
  1203.         break;
  1204.     case CAGD_PT_E1_TYPE:
  1205.     case CAGD_PT_E3_TYPE:
  1206.     case CAGD_PT_P3_TYPE:
  1207.         TSrf = CagdCoerceSrfTo(CrvtrSrfBound, PtType);
  1208.         CagdSrfFree(CrvtrSrfBound);
  1209.         CrvtrSrfBound = TSrf;
  1210.         break;
  1211.     default:
  1212.         CagdSrfFree(CrvtrSrfBound);
  1213.         IritPrsrFatalError("SCRVTR: Wrong point type coercion.");
  1214.         return NULL;
  1215.     }
  1216.  
  1217.     NewPObj = GenSRFObject(CrvtrSrfBound);
  1218.  
  1219.     return NewPObj;
  1220. }
  1221.  
  1222. /*****************************************************************************
  1223. * DESCRIPTION:                                                               M
  1224. * Computes the evolute curve of the given curve.                 M
  1225. *                                                                            *
  1226. * PARAMETERS:                                                                M
  1227. *   PObj:     Curve to compute its evolute curve for.                        M
  1228. *                                                                            *
  1229. * RETURN VALUE:                                                              M
  1230. *   IPObjectStruct *:   An evolute curve of PObj.                            M
  1231. *                                                                            *
  1232. * KEYWORDS:                                                                  M
  1233. *   CrvEvolute                                                               M
  1234. *****************************************************************************/
  1235. IPObjectStruct *CrvEvolute(IPObjectStruct *PObj)
  1236.     IPObjectStruct *NewPObj;
  1237.     CagdCrvStruct *EvoluteCrv, *EvoluteCrvAux;
  1238.  
  1239.     if (CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) < 2 ||
  1240.     CAGD_NUM_OF_PT_COORD(PObj -> U.Crvs -> PType) > 3) {
  1241.     IritPrsrFatalError(
  1242.         "CEVOLUTE: Only 2 or 3 dimensional curves are supported.");
  1243.     return NULL;
  1244.     }
  1245.  
  1246.     EvoluteCrvAux = SymbCrv3DRadiusNormal(PObj -> U.Crvs);
  1247.     EvoluteCrv = SymbCrvAdd(PObj -> U.Crvs, EvoluteCrvAux);
  1248.     CagdCrvFree(EvoluteCrvAux);
  1249.  
  1250.     NewPObj = GenCRVObject(EvoluteCrv);
  1251.  
  1252.     return NewPObj;
  1253. }
  1254.  
  1255. /*****************************************************************************
  1256. * DESCRIPTION:                                                               M
  1257. * Merges two surfaces into one in specified Dir and SameEdge flag.          M
  1258. *                                                                            *
  1259. * PARAMETERS:                                                                M
  1260. *   Srf1, Srf2:  Two surfaces to merge.                                      M
  1261. *   Dir:         Direction of merge. Either U or V.                          M
  1262. *   SameEdge:    Do Srf1 and Srf2 share a common edge?                       M
  1263. *                                                                            *
  1264. * RETURN VALUE:                                                              M
  1265. *   IPObjectStruct *:  A surface result of the merge.                        M
  1266. *                                                                            *
  1267. * KEYWORDS:                                                                  M
  1268. *   MergeSrfSrf                                                              M
  1269. *****************************************************************************/
  1270. IPObjectStruct *MergeSrfSrf(IPObjectStruct *Srf1,
  1271.                 IPObjectStruct *Srf2,
  1272.                 RealType *Dir,
  1273.                 RealType *SameEdge)
  1274. {
  1275.     IPObjectStruct *SrfObj;
  1276.     CagdSrfStruct
  1277.     *Srf = CagdMergeSrfSrf(Srf1 -> U.Srfs, Srf2 -> U.Srfs,
  1278.                    REAL_PTR_TO_INT(Dir), REAL_PTR_TO_INT(SameEdge),
  1279.                    TRUE);
  1280.  
  1281.     SrfObj = GenSRFObject(Srf);
  1282.  
  1283.     return SrfObj;
  1284. }
  1285.  
  1286. /*****************************************************************************
  1287. * DESCRIPTION:                                                               M
  1288. * Merge two curves/ctl points into one curve by adding a linear segment      M
  1289. * between the first end point to second start point.                 M
  1290. *                                                                            *
  1291. * PARAMETERS:                                                                M
  1292. *   PObj1, PObj2:  Either curve or a control point to merge.                 M
  1293. *                                                                            *
  1294. * RETURN VALUE:                                                              M
  1295. *   IPObjectStruct *:   Merged curve.                                        M
  1296. *                                                                            *
  1297. * KEYWORDS:                                                                  M
  1298. *   MergeCurvesAndCtlPoints                                                  M
  1299. *****************************************************************************/
  1300. IPObjectStruct *MergeCurvesAndCtlPoints(IPObjectStruct *PObj1,
  1301.                     IPObjectStruct *PObj2)
  1302. {
  1303.     IPObjectStruct *CrvObj;
  1304.     CagdCrvStruct
  1305.     *Crv = NULL;
  1306.     CagdPtStruct Pt1, Pt2;
  1307.  
  1308.     if (IP_IS_CRV_OBJ(PObj1)) {
  1309.     if (IP_IS_CRV_OBJ(PObj2)) {
  1310.         Crv = CagdMergeCrvCrv(PObj1 -> U.Crvs, PObj2 -> U.Crvs, TRUE);
  1311.     }
  1312.     else if (IP_IS_CTLPT_OBJ(PObj2)) {
  1313.         CagdRType
  1314.         *Coords2 = PObj2 -> U.CtlPt.Coords;
  1315.  
  1316.         CagdCoerceToE3(Pt2.Pt, &Coords2, -1, PObj2 -> U.CtlPt.PtType);
  1317.         Crv = CagdMergeCrvPt(PObj1 -> U.Crvs, &Pt2);
  1318.     }
  1319.     else
  1320.         IritFatalError("Curve/CtlPt was expected.");
  1321.     }
  1322.     else if (IP_IS_CTLPT_OBJ(PObj1)) {
  1323.     CagdRType
  1324.         *Coords1 = PObj1 -> U.CtlPt.Coords;
  1325.  
  1326.     CagdCoerceToE3(Pt1.Pt, &Coords1, -1, PObj1 -> U.CtlPt.PtType);
  1327.  
  1328.     if (IP_IS_CRV_OBJ(PObj2)) {
  1329.         Crv = CagdMergePtCrv(&Pt1, PObj2 -> U.Crvs);
  1330.     }
  1331.     else if (IP_IS_CTLPT_OBJ(PObj2)) {
  1332.         CagdRType
  1333.         *Coords2 = PObj2 -> U.CtlPt.Coords;
  1334.  
  1335.         CagdCoerceToE3(Pt2.Pt, &Coords2, -1, PObj2 -> U.CtlPt.PtType);
  1336.         Crv = CagdMergePtPt(&Pt1, &Pt2);
  1337.     }
  1338.     else
  1339.         IritFatalError("Curve/CtlPt was expected.");
  1340.     }
  1341.     else
  1342.     IritFatalError("Curve/CtlPt was expected.");
  1343.  
  1344.     if (Crv == NULL)
  1345.     return NULL;
  1346.  
  1347.     CrvObj = GenCRVObject(Crv);
  1348.  
  1349.     return CrvObj;
  1350. }
  1351.